using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Rogan.Utility.Common;

namespace Rogan.Utility.Linq
{
	public abstract class QueryProvider : IQueryProvider
	{
		IQueryable<S> IQueryProvider.CreateQuery<S>(Expression expression)
		{
			return new Queryable<S>(this, expression);
		}
		IQueryable IQueryProvider.CreateQuery(Expression expression)
		{
			Type elementType = TypeHelper.GetElementType(expression.Type);
			IQueryable result;
			try
			{
				result = (IQueryable)Activator.CreateInstance(typeof(Queryable<>).MakeGenericType(new[]
				{
					elementType
				}), new object[]
				{
					this,
					expression
				});
			}
			catch (TargetInvocationException ex)
			{
				throw ex.InnerException;
			}
			return result;
		}
		S IQueryProvider.Execute<S>(Expression expression)
		{
			return (S)((object)this.Execute(expression));
		}
		object IQueryProvider.Execute(Expression expression)
		{
			return this.Execute(expression);
		}
		public abstract string GetQueryText(Expression expression);
		public abstract object Execute(Expression expression);
	}
}
